/*
 *      Author: Guannan Ma
 *      @mythmgn
 *      Whatever license applied
 */

#include "base.h"
#include <pthread.h>

static pthread_key_t errKey;
static pthread_once_t errKeyOnce = PTHREAD_ONCE_INIT;

const char * const wasGlobalMsg[]={
	"No Error",
    "Memory allocation failed",
    "File does not exist",
    "Opening file failed",
    "Item already exist",
    "Item not found",
    "Reach the maximum slots limit",
    "Input format is not valid",
    "Initial - failure",
    "Initial - not inited",
    "Error End"
};

static void makeKeyForErr(){
	(void) pthread_key_create(&errKey, NULL);
}

static void initKeyForErr(){
	(void) pthread_once(&errKeyOnce, makeKeyForErr);
}

static int32* getKeyPonter(){
	uint32 *pErr;
	initKeyForErr();
    if ((pErr = (uint32*) pthread_getspecific(errKey)) == NULL) {
    	pErr = (uint32*)malloc(sizeof(uint32));
    	*pErr = GLOBAL_NO_ERR;
        (void) ( pthread_setspecific(errKey, (void*)pErr) );
    }
    ASSERT((*pErr)<ERROR_END);
    return pErr;
}

const char *const getErrMsg() {
	uint32 *pErr=getKeyPonter();
	ASSERT(pErr!=NULL);
    return (const char * const) (wasGlobalMsg[*pErr]);
}

const uint32 getErrStatusCode(){
	uint32 *pErr=getKeyPonter();
	return *pErr;
}

BOOL setErrStatusCode(uint32 errCode){
	uint32 *pErr=getKeyPonter();
	ASSERT(pErr!=NULL);
	ASSERT(errCode < ERROR_END);
	*pErr = errCode;
    return TRUE;
}
